home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dvips / virtualfont.c < prev   
Encoding:
C/C++ Source or Header  |  1990-01-05  |  7.0 KB  |  284 lines

  1. /*
  2.  *   Here's the code to load a VF file into memory.
  3.  *   Any resemblance between this file and loadfont.c is purely uncoincidental.
  4.  */
  5. #include "structures.h" /* The copyright notice in that file is included too! */
  6. /*
  7.  *   These are the external routines we use.
  8.  */
  9. extern void makefont() ;
  10. extern void error() ;
  11. extern integer scalewidth() ;
  12. extern FILE *search() ;
  13. /*
  14.  *   These are the external variables we use.
  15.  */
  16. #ifdef DEBUG
  17. extern integer debug_flag;
  18. #endif  /* DEBUG */
  19. extern long bytesleft ;
  20. extern quarterword *raster ;
  21. extern char *vfpath ;
  22. extern char errbuf[200] ;
  23. extern real conv ;
  24. extern real alpha ;
  25. extern integer mag ;
  26. extern int actualdpi ;
  27. extern char *nextstring, *maxstring ;
  28. extern fontdesctype *fonthead ;
  29. extern real alpha ;
  30. /*
  31.  *   We use malloc here.
  32.  */
  33. char *malloc() ;
  34.  
  35. /*
  36.  *   Now we have some routines to get stuff from the VF file.
  37.  *   Subroutine vfbyte returns the next byte.
  38.  */
  39.  
  40. static FILE *vffile ;
  41. static char name[50] ;
  42. void
  43. badvf(s)
  44.    char *s ;
  45. {
  46.    (void)sprintf(errbuf,"! Bad VF file %s: %s",name,s) ;
  47.    error(errbuf);
  48. }
  49.  
  50. shalfword
  51. vfbyte()
  52. {
  53.    register shalfword i ;
  54.  
  55.    if ((i=getc(vffile))==EOF)
  56.       badvf("unexpected eof") ;
  57.    return(i) ;
  58. }
  59.  
  60. integer
  61. vfquad()
  62. {
  63.    register integer i ;
  64.  
  65.    i = vfbyte() ;
  66.    if (i > 127)
  67.       i -= 256 ;
  68.    i = i * 256 + vfbyte() ;
  69.    i = i * 256 + vfbyte() ;
  70.    i = i * 256 + vfbyte() ;
  71.    return(i) ;
  72. }
  73.  
  74. integer
  75. vftrio()
  76. {
  77.    register integer i ;
  78.  
  79.    i = vfbyte() ;
  80.    i = i * 256 + vfbyte() ;
  81.    i = i * 256 + vfbyte() ;
  82.    return(i) ;
  83. }
  84.  
  85. Boolean
  86. vfopen(fd)
  87.         register fontdesctype *fd ;
  88. {
  89.    register char *d, *n ;
  90.  
  91.    d = fd->area ;
  92.    n = fd->name ;
  93.    if (*d==0)
  94.       d = vfpath ;
  95.    (void)sprintf(name, "%s.vf", n) ;
  96.    if (vffile=search(d, name))
  97.       return(1) ;
  98.    return(0) ;
  99. }
  100.  
  101. /*
  102.  * The following routine is like fontdef, but for local fontdefs in VF files.
  103.  */
  104. fontmaptype *
  105. vfontdef(s)
  106.       integer s ;
  107. {
  108.    register integer i, j, fn ;
  109.    register fontdesctype *fp, *fpp ;
  110.    register fontmaptype *cfnt ;
  111.  
  112.    fn = vfbyte() ;
  113.    fp = (fontdesctype *)malloc(sizeof(fontdesctype)) ;
  114.    cfnt = (fontmaptype *)malloc(sizeof(fontmaptype)) ;
  115.    if (fp==NULL || cfnt==NULL)
  116.       error("! ran out of memory") ;
  117.    cfnt->fontnum = fn ;
  118.    fp->psname = 0 ;
  119.    fp->loaded = 0 ;
  120.    fp->checksum = vfquad() ;
  121.    fp->scaledsize = scalewidth(s,vfquad()) ;
  122.    fp->designsize = (integer)(alpha * (real)vfquad()) ;
  123.    fp->thinspace = fp->scaledsize / 6 ;
  124.    fp->resfont = NULL ;
  125.    fp->localfonts = NULL ;
  126.    fp->dpi = (halfword)((float)mag*(float)fp->scaledsize*DPI/
  127.          ((float)fp->designsize*1000.0)+0.5) ;
  128.    i = vfbyte() ; j = vfbyte() ;
  129.    if (nextstring + i + j > maxstring)
  130.       error("! out of string space") ;
  131.    fp->area = nextstring ;
  132.    for (; i>0; i--)
  133.       *nextstring++ = vfbyte() ;
  134.    *nextstring++ = 0 ;
  135.    fp->name = nextstring ;
  136.    for (; j>0; j--)
  137.       *nextstring++ = vfbyte() ;
  138.    *nextstring++ = 0 ;
  139. #ifdef DEBUG
  140.    if (dd(D_FONTS))
  141.       (void)fprintf(stderr,"Defining localfont (%s) %s at %.1fpt\n",
  142.          fp->area, fp->name, (real)fp->scaledsize/(alpha*0x100000)) ;
  143. #endif /* DEBUG */
  144.    for (fpp=fonthead; fpp; fpp=fpp->next)
  145.       if (fp->scaledsize==fpp->scaledsize &&
  146.             strcmp(fp->name,fpp->name)==0 && strcmp(fp->area,fpp->area)==0) {
  147. #ifdef DEBUG
  148.          if (dd(D_FONTS))
  149.             (void)fprintf(stderr,"(Already known.)\n") ;
  150. #endif /* DEBUG */
  151.          free((char *)fp) ;
  152.          fp = fpp ;
  153.          goto alreadyknown ;
  154.       }
  155.    fp->next = fonthead ;
  156.    fonthead = fp ;
  157. alreadyknown:
  158.    cfnt->desc = fp ;
  159.    return (cfnt) ;
  160. }
  161.  
  162. /*
  163.  *   Now our virtualfont routine.
  164.  */
  165. Boolean
  166. virtualfont(curfnt)
  167.         register fontdesctype *curfnt ;
  168. {
  169.    register shalfword i ;
  170.    register shalfword cmd ;
  171.    register integer k ;
  172.    register integer length ;
  173.    register shalfword cc ;
  174.    register chardesctype *cd ;
  175.    integer scaledsize = curfnt->scaledsize ;
  176.    register quarterword *tempr ;
  177.    fontmaptype *fm, *newf ;
  178.  
  179.    if (!vfopen(curfnt))
  180.       return (0) ;
  181. #ifdef DEBUG
  182.    if (dd(D_FONTS))
  183.       (void)fprintf(stderr,"Loading virtual font %s at %.1fpt\n",
  184.          name, (real)scaledsize/(alpha*0x100000)) ;
  185. #endif /* DEBUG */
  186.  
  187. /*
  188.  *   We clear out some pointers:
  189.  */
  190.    for (i=0; i<256; i++) {
  191.       curfnt->chardesc[i].TFMwidth = 0 ;
  192.       curfnt->chardesc[i].packptr = NULL ;
  193.       curfnt->chardesc[i].pixelwidth = 0 ;
  194.       curfnt->chardesc[i].flags = 0 ;
  195.    }
  196.    if (vfbyte()!=247)
  197.       badvf("expected pre") ;
  198.    if (vfbyte()!=202)
  199.       badvf("wrong id byte") ;
  200.    for(i=vfbyte(); i>0; i--)
  201.       (void)vfbyte() ;
  202.    k = vfquad() ;
  203.    if (k && curfnt->checksum)
  204.       if (k!=curfnt->checksum) {
  205.          (void)sprintf(errbuf,"Checksum mismatch in font %s", name) ;
  206.          error(errbuf) ;
  207.        }
  208.    k = (integer)(alpha * (real)vfquad()) ;
  209.    if (k > curfnt->designsize + 2 || k < curfnt->designsize - 2) {
  210.       (void)sprintf(errbuf,"Design size mismatch in font %s", name) ;
  211.       error(errbuf) ;
  212.    }
  213. /*
  214.  * Now we look for font definitions.
  215.  */
  216.    fm = NULL ;
  217.    while ((cmd=vfbyte())>=243) {
  218.       if (cmd!=243)
  219.          badvf("unexpected command in preamble") ;
  220.       newf = vfontdef(scaledsize) ;
  221.       if (fm)
  222.          fm->next = newf ;
  223.       else curfnt->localfonts = newf ;
  224.       fm = newf ;
  225.       fm->next = NULL ; /* FIFO */
  226.    }
  227. /*
  228.  *   Now we get down to the serious business of reading character definitions.
  229.  */
  230.    do {
  231.       if (cmd==242) {
  232.          length = vfquad() + 2 ;
  233.          if (length<2) badvf("negative length packet") ;
  234.          if (length>65535) badvf("packet too long") ;
  235.          cc = vfquad() ;
  236.          if (cc<0 || cc>255) badvf("character code out of range") ;
  237.          cd = curfnt->chardesc + cc ;
  238.          cd->TFMwidth = scalewidth(vfquad(), scaledsize) ;
  239.       } else {
  240.          length = cmd + 2;
  241.          cc = vfbyte() ;
  242.          cd = curfnt->chardesc + cc ;
  243.          cd->TFMwidth = scalewidth(vftrio(), scaledsize) ;
  244.       }
  245.       cd->pixelwidth = ((integer)(conv*cd->TFMwidth+0.5)) ;
  246.       cd->flags = EXISTS ;
  247.       if (bytesleft < length) {
  248. #ifdef DEBUG
  249.           if (dd(D_FONTS))
  250.              (void)fprintf(stderr,
  251.                    "Allocating new raster memory (%d req, %d left)\n",
  252.                                 length, bytesleft) ;
  253. #endif /* DEBUG */
  254.           if (length > MINCHUNK) {
  255.              tempr = (quarterword *)malloc((unsigned int)length) ;
  256.              bytesleft = 0 ;
  257.           } else {
  258.              raster = (quarterword *)malloc(RASTERCHUNK) ;
  259.              tempr = raster ;
  260.              bytesleft = RASTERCHUNK - length ;
  261.              raster += length ;
  262.          }
  263.          if (tempr == NULL)
  264.             error("! out of memory while allocating raster") ;
  265.       } else {
  266.          tempr = raster ;
  267.          bytesleft -= length ;
  268.          raster += length ;
  269.       }
  270.       cd->packptr = tempr ;
  271.       length -= 2 ;
  272.       *tempr++ = length / 256 ;
  273.       *tempr++ = length % 256 ;
  274.          for (; length>0; length--)
  275.             *tempr++ = vfbyte() ;
  276.       cmd = vfbyte() ;
  277.    } while (cmd < 243) ;
  278.    if (cmd != 248)
  279.       badvf("missing postamble") ;
  280.    (void)fclose(vffile) ;
  281.    curfnt->loaded = 2 ;
  282.    return (1) ;
  283. }
  284.